package com.geo.geotool.service.trans;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.esri.core.geometry.*;
import com.geo.geotool.entity.enmu.GeoFormatEnum;
import org.apache.commons.lang3.StringUtils;


/**
 * • @Description: 地理数据格式转换
 * • @author  : yell
 * • @date : 2021/12/10  18:19
 */
public class GeometryFormatTrans implements IGeometryFormatTrans{

    @Override
    public String geoFormatTrans(String jsonString, String... param) throws Exception{
        String inFormat = GeometryFormatCapture.capture(jsonString);
        if(param != null &&param.length>0 &&  StringUtils.isNotEmpty(param[0])){
            inFormat = param[0];
        }
        String tarFormat = IGeometryFormatTrans.defaultTargetGeoFormat;
        if(param != null && param.length>1 && StringUtils.isNotEmpty(param[1])){
            tarFormat = param[1];
        }
        String srId = null;
        if(inFormat.equals(GeoFormatEnum.WKT.getType())){
            if(param!=null && param.length > 2 && StringUtils.isNotEmpty(param[2])){
                srId = param[2];
            }else {
                srId = "4326";
            }
            MapGeometry geometry = new MapGeometry(OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults,Geometry.Type.Unknown,jsonString,null),null);
            if(tarFormat.equals(GeoFormatEnum.GeoJSON.getType())){
                return OperatorExportToGeoJson.local().execute(geometry.getGeometry());
            }else if(tarFormat.equals(GeoFormatEnum.WKT.getType())){
                return jsonString;
            }else if(tarFormat.equals(GeoFormatEnum.EsriJSON.getType())){
                return OperatorExportToJson.local().execute(geometry.getSpatialReference(),geometry.getGeometry());
            }

        }
        return transToTarget(jsonString,inFormat,tarFormat,srId);
    }

    private String transToTarget(String jsonString, String inFormat,String targetFormat,String srId){
        String targetGeoString = "";
        /**geoType*/
        if(inFormat.equals(targetFormat)){
            return jsonString;
        }

        Object jObject = JSON.parse(jsonString);
        if(jObject instanceof JSONArray) {
            JSONArray inArray = (JSONArray) jObject;
            JSONArray targetList = new JSONArray();
            for (int i = 0; i < inArray.size(); i++) {
                MapGeometry inGeometry = inToGeometry(inArray.getJSONObject(i), inFormat);
                if (inFormat.equals(GeoFormatEnum.WKT.getType()) && StringUtils.isNotEmpty(srId)) {
                    inGeometry.setSpatialReference(SpatialReference.create(srId));
                }
                String jo = geometryToTarget(inGeometry, targetFormat);
                targetList.add(jo);
                targetGeoString = targetList.toJSONString();
            }
        }else {
            MapGeometry inGeometry = inToGeometry((JSONObject) jObject, inFormat);
            if (inFormat.equals(GeoFormatEnum.WKT.getType()) && StringUtils.isNotEmpty(srId)) {
                inGeometry.setSpatialReference(SpatialReference.create(srId));
            }
            targetGeoString = geometryToTarget(inGeometry, targetFormat);
        }
        return targetGeoString;
    }


    private MapGeometry inToGeometry(JSONObject jo , String inFormat){
        MapGeometry geometry = null;
        if(inFormat.equals(GeoFormatEnum.GeoJSON.getType())){
            geometry = OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults,
                    Geometry.Type.Unknown,jo.toJSONString(),null);
        }else if(inFormat.equals(GeoFormatEnum.WKT.getType())){
            geometry = new MapGeometry(OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults,Geometry.Type.Unknown,jo.toJSONString(),null),null);
        }else if(inFormat.equals(GeoFormatEnum.EsriJSON.getType())){
            geometry = OperatorImportFromJson.local().execute(Geometry.Type.Unknown,jo.toJSONString());
        }
        return geometry;
    }

    private String geometryToTarget(MapGeometry geometry,String outFormat){
        String geoStr = "";
        if(outFormat.equals(GeoFormatEnum.GeoJSON.getType())){
            geoStr = OperatorExportToGeoJson.local().execute(geometry.getGeometry());
        }else if(outFormat.equals(GeoFormatEnum.WKT.getType())){
            geoStr = OperatorExportToWkt.local().execute(WktExportFlags.wktExportDefaults,geometry.getGeometry(),null);
        }else if(outFormat.equals(GeoFormatEnum.EsriJSON.getType())){
            geoStr = OperatorExportToJson.local().execute(geometry.getSpatialReference(),geometry.getGeometry());
        }
        return geoStr;
    }
}